package cz.semjob.framework;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import weka.classifiers.Classifier;
import cz.semjob.document.annotation.metadata.AnnotationTypeFactory;
import cz.semjob.document.annotation.metadata.Entity;
import cz.semjob.document.annotation.metadata.Relation;
import cz.semjob.document.util.FileUtil;
import cz.semjob.framework.util.PropertiesUtil;
import cz.semjob.learning.classifier.io.ClassifierIO;
import cz.semjob.learning.data.TaxonomyLearningException;
import cz.semjob.learning.instances.creator.IInstanceCreator;

@Component
public class ClassifierInstanceCreatorReader {

	@Autowired
	private AnnotationTypeFactory annotationTypeFactory;
	@Autowired
	private ClassifierIO classifierIO;

	public List<ClassifierInstanceCreatorPair> readClassifiers(
			String classifierPath, boolean concepts) throws DocumentAnnotationException {
		
		File classifiersDirectory = new File(classifierPath);
		if (!classifiersDirectory.isDirectory()) {
			throw new DocumentAnnotationException(
					"Classifiers directory is not a directory: "
							+ classifiersDirectory.getAbsolutePath());
		}

		List<ClassifierInstanceCreatorPair> classifiers = new ArrayList<ClassifierInstanceCreatorPair>();
		for (String inputTextFilePath : classifiersDirectory.list(FileUtil
				.getDirectoryFilenameFilter())) {
			String annotationType = null;
			if (concepts) {
				Entity entity = annotationTypeFactory
					.getEntity(inputTextFilePath);
				if (entity != null) {
					annotationType = entity.getName();
				}
			} else {
				List<Relation> relations = annotationTypeFactory.getRelationsByType(inputTextFilePath);
				if (relations != null) {
					annotationType = inputTextFilePath;
				}
			}
			if (annotationType == null) {
				continue;
			}

			File inputTextFile = new File(classifiersDirectory,
					inputTextFilePath);
			// TODO nazov do kontanty
			File classifierFile = new File(inputTextFile, "classifier.object");
			File textInstanceCreatorFile = new File(inputTextFile,
					"instanceCreator.object");
			File infoFile = new File(inputTextFile,
					"info.properties");

			if (!classifierFile.isFile() || !textInstanceCreatorFile.isFile() || !infoFile.isFile()) {
				throw new DocumentAnnotationException(
						"Could not find classifer or instance creator object or info file in directory: "
								+ inputTextFile);
			}

			Classifier classifier = null;
			IInstanceCreator textInstanceCreator = null;
			Properties properties = null;
			try {
				classifier = classifierIO
						.importClassifierFromFile(classifierFile
								.getAbsolutePath());
				textInstanceCreator = classifierIO
						.importTextInstanceCreator(textInstanceCreatorFile
								.getAbsolutePath());
				properties = PropertiesUtil.readProperties(infoFile.getAbsolutePath());

			} catch (TaxonomyLearningException e) {
				throw new DocumentAnnotationException(e);
			} catch (IOException e) {
				throw new DocumentAnnotationException(e);
			}

			ClassifierInstanceCreatorPair classifierInstanceCreatorPair = new ClassifierInstanceCreatorPair(
					annotationType, classifier, textInstanceCreator);
			Double precision = PropertiesUtil.getDouble("precision", properties);
			Double recall = PropertiesUtil.getDouble("recall", properties);
			Double fmeasure = PropertiesUtil.getDouble("fmeasure", properties);
			String classifierInfo = properties.getProperty("classifier");
			classifierInstanceCreatorPair.setClassifierInfo(precision, recall, fmeasure, classifierInfo);
			classifiers.add(classifierInstanceCreatorPair);
		}

		return classifiers;

	}

	public void setAnnotationTypeFactory(
			AnnotationTypeFactory annotationTypeFactory) {
		this.annotationTypeFactory = annotationTypeFactory;
	}

	public void setClassifierIO(ClassifierIO classifierIO) {
		this.classifierIO = classifierIO;
	}

}
